home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-05-02 | 46.7 KB | 1,368 lines |
- 2 FONTS
-
- 2.1 INTRODUCTION
-
- In the previous chapters when we have printed text with help
- of the low level Text() function or the high level IntuiText
- structure, we have always used a font called "Topaz". The
- reason why we always have used this font is simply because it
- is the Amiga's default font and exist in ROM.
-
- Topaz is, however, not the only font available on the Amiga.
- There exist thousands more, but these are not placed in ROM,
- they are loaded from disks. Loading fonts from disks is luckily
- quite a simple task since all necessary functions have already
- been written and exist in the "Diskfont Library".
-
- In this chapter I will show you how to open the Diskfont
- Library, and use its functions. This involves finding out
- which fonts are available, loading them into memory and
- how to use them. I will also explain how to create your own
- fonts and use them in your own programs.
-
-
-
- 2.2 FONTS
-
- A font is a collection of graphical objects that represents
- characters. Since the Amiga was built as a graphical work
- station the system has been designed to handle all different
- types of fonts with great efficiency. Fonts of almost any size
- can be used, and the Amiga can itself convert fonts to styles
- like italic, underlined, bold, extended, and all possible
-
- All fonts have a "Baseline" on which the characters are placed.
- Characters like "abcdef" will all be on and above the baseline.
- On the other hand, characters like "gjpqy" will also use some
- space under the baseline.
-
- Here are three letters - 'a' 'b' and 'g'. As you can see will
- the 'g' use same space below the baseline. (The baseline is
- like normal rows on a paper.)
-
- #
- #
- #### #
- # #
- # #
- # #
- ##### ##### #####
- # # # # # #
- # # # # # #
- # # # # # #
- # # # # # #
- ###### ##### ##### <= Baseline
- #
- #
- # #
- ####
-
-
-
-
- 2.3 ROM FONTS
-
- As said above, there exist for the moment only one ROM based
- font on the Amiga. It is Topaz and exist in two sizes, 8 and
- 9 pixels high. (ROM is like the normal memory in a computer,
- but when the computer is turned off the contents will still be
- intact. The disadvantage is that you can not change anything
- which is stored in ROM. ROM - "Read Only Memory".)
-
- Topaz two sizes:
-
- - 9 pixels high (32 characters/row low resolution)
- (64 - " - high resolution)
- - 8 pixels high (40 - " - low resolution)
- (80 - " - high resolution)
-
- Note! The limit on how many characters/row you can print simply
- depends on the width of the screen. In the above example I
- assume that low resolution means a 320 pixels wide display,
- and high resolution 640 pixels wide screen. Nowadays you can
- not be sure what the maximum width is simply because many
- users are now working on displays with overscan, extra large
- screens, see previous chapter for more information. I my
- self is currently using a 736 pixels wide and 540 lines tall
- display.
-
-
-
- 2.3.1 TEXTATTR STRUCTURE
-
- When you want to use a font you allocate a TextAttr structure
- (defined in the header file "graphics/text.h"). In the
- structure you write your requirements, the name of the font,
- height, style (normal, underlined, bold, italic...) and what
- type it is (if the font exist in ROM or on Disk).
-
- The TextAttr structure look like this:
-
- struct TextAttr
- {
- STRPTR ta_Name;
- UWORD ta_YSize;
- UBYTE ta_Style;
- UBYTE ta_Flags;
- };
-
- ta_Name: Name of the font together with the extension ".font".
- For example: To get the font Topaz you should write
- "topaz.font".
-
- ta_YSize: The Height of the font. To get a 9 pixel high font
- simply write 9.
-
- ta_Style: There exist five different styles that may be
- combined. The styles are: Normal, Underlined, Bold
- Italic and Extended. You specify which styles you
- want to use with the following flags: FS_NORMAL,
- FSF_UNDERLINED, FSF_BOLD, FSF_ITALIC and
- FSF_EXTENDED.
-
- To get a combination (e.g. Bold and Italic) use the
- binary OR operator "|" (e.g. FSF_BOLD | FSF_ITALIC).
-
- Note! If you ask for an underlined font for example,
- it is not sure there exist one. You should then get
- the font you want in the normal style, and then
- change it with help of the SetSoftStyle() function.
- (Explained later in this chapter.)
-
- ta_Flags: This field tells the Amiga what type of font you
- want. If it is a ROM based font write FPF_ROMFONT.
- If it is a disk based font write FPF_DISKFONT.
- (See below for a complete Flag list.)
-
-
- If you want to use the ROM font Topaz, 9 pixels high, normal
- style, you should initialize the TextAttr structure like this:
-
-
- struct TextAttr my_font_attr=
- {
- "topaz.font", /* Name of the font. */
- 9, /* Height (in pixels) */
- FS_NORMAL, /* Style */
- FPF_ROMFONT /* Exist in ROM. */
- };
-
-
-
- 2.3.2 OPEN ROM FONTS
-
- After you have initialized the TextAttr structure you call the
- OpenFont() function to get access to a ROM font. The Amiga will
- open the font which closes matches your requirements in the
- TaxtAttr structure. If OpenFont() finds the font it returns a
- pointer to a TextFont structure and tells the system that you
- are using the font.
-
- Synopsis: font = OpenFont( attr );
-
- font: (struct TextFont *) Pointer to a TextFont structure
- which is declared in header file "graphics/text.h".
- See below for more information about this structure.
- If OpenFont() could not find the font it returns
- NULL.
-
- attr: (struct TextAttr *) Pointer to an already initialized
- TextAttr structure. OpenFont() will try to open the
- font which closes matches your requirements.
-
-
-
- 2.3.3 CLOSE ROM FONTS
-
- All fonts you have opened must be "closed" before your program
- terminates! Since the font is in ROM no memory would be wasted
- if you forgot to close a previously opened font, but your
- program code would not look very good, so be careful. Close
- a font by calling the CloseFont() function.
-
- Synopsis: CloseFont( font );
-
- font: (struct TextFont *) Pointer to a previously opened
- TextFont structure. Note that you should NOT try to
- close a font which you have not opened!
-
-
-
- 2.4 DISK FONTS
-
- Most fonts does not exist in ROM but are loaded from disks.
- The greatest advantage of loading fonts rather than including
- the fonts with the program itself is that several programs
- running at the same time can all use the same set of fonts.
- A lot of memory is therefore saved.
-
-
-
- 2.4.1 DISKFONT LIBRARY
-
- Most of the special routines which are involved with loading
- and using disk fonts are automatically taken care of by the
- Diskfont Library. Whenever you want to use disk fonts you
- should remember to open this library.
-
- The diskfont library is opened as all other libraries with an
- OpenLibrary() call, and closed by and CloseLibrary() call. If
- the diskfont library not have already been opened by some
- other program it will be loaded from the system disk. (From
- the logical device "LIBS:", named "diskfont.library".
-
- Here is an example:
-
- struct Library *DiskfontBase;
-
- DiskfontBase = (struct DiskfontBase *)
- OpenLibrary( "diskfont.library", 0 );
-
- if( !DiskfontBase )
- clean_up( "Could not open Diskfont library!" );
-
- ...
-
- if( DiskfontBase )
- CloseLibrary( DiskfontBase );
-
-
-
- 2.4.2 FINDING OUT WHICH FONTS ARE AVAILABLE
-
- After you have opened the diskfont library you can use the
- special function AvailFonts() which will scan through the
- font directory of the system disk, and return a complete list
- of available fonts.
-
- Synopsis: missing = AvailFonts( buffer, size, type );
-
- missing: (long) If the buffer was not big enough to store the
- complete list of fonts in the extra number of bytes
- needed is returned. If 0 is returned the buffer was
- big enough for a complete list of fonts.
-
- buffer: (char *) Pointer to some memory were the list of
- fonts can be stored.
-
- size: (long) The size of the buffer (in bytes).
-
- type: (long) If you want to look for available fonts which
- are already in the memory set the flag "AFF_MEMORY".
- If you want to search the disk for available fonts,
- set the flag "AFF_DISK". To search both the memory
- and the disk set both flags with the binary OR
- operator between ("AFF_DISK | AFF_MEMORY").
-
- The font list consists of a AvailFontsHeader structure followed
- by a list of AvailFonts structures (both declared in header
- file "libraries/diskfont.h"):
-
- struct AvailFontsHeader
- {
- UWORD afh_NumEntries;
- };
-
- afh_NumEntries: Number of AvailFonts structures.
-
-
- struct AvailFonts
- {
- UWORD af_Type;
- struct TextAttr af_Attr;
- };
-
- af_Type: If the font exist in memory the "AFF_MEMORY" flag is
- set. If the font exist on the disk the "AFF_DISK" flag
- is set.
-
- af_Attr: An initialized TextAttr structure. This structure can
- be examined to find the font's name, size, style etc...
- (See above for more information about the TextAttr
- structure.)
-
-
- It is impossible to know how big memory buffer you need for the
- AvailFonts() function. You can of course allocate a very big
- buffer and be quite sure it will be big enough, but this is not
- a good solution. A lot of memory is wasted if the buffer is too
- big, and it may happen that the buffer still is too small. The
- solution to this problem is to call the AvailFonts() function
- with the buffer size set to 0. AvailFonts() will then return
- the number of bytes needed to store the complete list. Allocate
- a buffer with this size, and call the AvailFonts() function
- once again, but this time give it the new buffer.
-
- Here is an example:
-
- int size;
- struct AvailFontsHeader *avail_fonts_header;
- struct AvailFonts *avail_fonts;
-
- /* Find out which fonts are available both in the memory */
- /* as well on the disk. The buffer size is set to 0, hence */
- /* the function will return the correct number of bytes */
- /* needed to store the complete list in: */
- size = AvailFonts( NULL, 0, AFF_DISK | AFF_MEMORY );
-
- /* Allocate the buffer: (Now we know what size is needed.) */
- avail_fonts_header = (struct AvailFontsHeadr *)
- AllocMem( size, MEMF_CLEAR );
-
- /* Call the function AvailFonts() again, but this time we give */
- /* it a buffer to store the information in: (Remember to still */
- /* check that the buffer was big enough! Some other task could */
- /* have changed something in the FONTS: device while we */
- /* allocated the buffer. Never trust the Amiga...) */
- if( AvailFonts( avail_fonts_header, size, AFF_DISK | AFF_MEMORY ) )
- clean_up( "Buffer to small to store the font list in!" );
-
- /* We can now examine the list. See example 5. */
-
-
- When the Amiga tries to load a font it looks in the logical
- device "FONTS:". If you have more fonts on another disk you
- can reassign the logical device "FONTS:" with help of the
- AmigaDOS command "Assign". If you have a collection of nice
- fonts in the drawer "MyFonts" on the disk in "df1:" you
- call Assign like this: "Assign FONTS: df1:MyFonts" (without
- quotations)
-
-
-
- 2.4.3 OPEN DISK FONTS
-
- You "open" a disk font by initializing a TextAttr structure
- with your requirements and call the OpenDiskFont() function.
- Remember that the diskfont library must have been opened before
- you may use this or the AvailFonts() function. If the font have
- not already been loaded into the memory by some other program
- it will automatically be done.
-
- Synopsis: font = OpenDiskFont( attr );
-
- font: (struct TextFont *) Pointer to a TextFont structure
- which is declared in header file "graphics/text.h".
- See below for more information about this structure.
-
- attr: (struct TextAttr *) Pointer to an already initialized
- TextAttr structure. OpenDiskFont() will try to open
- the font which closes matches your requirements.
-
-
- 2.4.4 CLOSE DISK FONTS
-
- All fonts you have opened must be closed before your program
- terminates. A lot of memory is otherwise wasted. Please be very
- careful with this! You close a font with the CloseFont()
- function as described above. Both ROM and Disk fonts are closed
- with this function.
-
- Synopsis: CloseFont( font );
-
- font: (struct TextFont *) Pointer to a previously opened
- TextFont structure. Note that you should NOT try to
- close a font which you have not opened!
-
-
-
- 2.5 USE THE NEW FONTS
-
- Once you have successfully opened the desired fonts you may
- start to use them. As described in the beginning of this
- chapter you can either use the low level functions Move() and
- Text() or the high level IntuiText structures.
-
-
-
- 2.5.1 HIGH LEVEL
-
- The high level approach is a clean and nice way to print text.
- For short messages it can be a bit tedious since you need to
- use some structures just to print some text. These structures
- that can feel a bit complicated and unnecessary are extremely
- useful and easy to handle if a lot of text is needed. The
- advantage with these structures is that they can easily be
- combined with each other as well as with other objects like
- gadgets, requesters, etc...
-
- Here is what you have to do:
-
- 1. Initialize a TextAttr structure with your requirements
- as described above.
-
- 2. Open the desired font as have also been described above.
-
- 3. Initialize the IntuiText structures as normal (see
- chapter 3 Graphics) but set the ITextFont pointer to the
- desired TextAttr structure.
-
- 4. Either connect the IntuiTedxt structure to an object
- (gadget, requester etc...) or print it directly with help
- of the PrintIText() function.
-
-
- Here is an example: ("my_window" is a pointer to an already
- opened window.)
-
- /* Pointer to the diskfont library: */
- struct Library *DiskfontBase;
-
- /* The attributes for our desired font: */
- struct TextAttr my_font_attr=
- {
- "Courier.font", /* Name of the font. */
- 18, /* Height, 18 pixels tall. */
- FS_NORMAL, /* Style, normal. */
- FPF_DISKFONT /* Load it from the disk. */
- };
-
- /* Intuition's text structure: */
- struct IntuiText my_intui_text=
- {
- 1, /* FrontPen, colour register 1. */
- 2, /* BackPen, colour register 2. */
- JAM2, /* DrawMode, draw the characters with colour 1, */
- /* on a colour 2 background. */
- 10, 20, /* LeftEdge, TopEdge. Position of the text. */
- &my_font_attr, /* ITextFont, use the Courier font. */
- "Hello", /* IText, the text that will be printed. */
- NULL, /* NextText, last structure in the list. */
- };
-
-
- /* Open the Intuition Library, windows etc... */
-
-
- /* Open the DiskFont library: */
- DiskfontBase = (struct DiskfontBase *)
- OpenLibrary( "diskfont.library", 0 );
- if( !DiskfontBase )
- clean_up( "Could not open Diskfont library!" );
-
-
- /* Open the desired font: */
- font = OpenDiskFont( &my_font_attr );
-
-
- /* Tell Intuition to print the text: */
- PrintIText( my_window->RPort, &my_intui_text, 0, 0 );
-
-
- /* Close the DiskFont Library: */
- if( DiskfontBase )
- CloseLibrary( DiskfontBase );
-
-
- /* Close the window, Intuition Library etc... */
-
-
-
- 2.5.2 LOW LEVEL
-
- When it is very little text that should be printed, or you do
- not want to mess around with structures you can use the low
- level functions Move() and Text(). Before you can use these
- functions you have to (of course) open the font as normal, but
- also tell the RastPort to use the new font. Use the SetFont()
- function to change a RastPort's default font.
-
- Synopsis: error = SetFont( rp, font );
-
- error: (long) If OK 0 is returned, else an error number is
- returned which means something went wrong.
-
- rp: (struct RastPort *) Pointer to the RastPort that
- should be affected.
-
- font: (struct TextFont *) Pointer to a TextFont structure
- which has previously been "opened".
-
-
-
- The the first character of the text will be printed at the
- Rastport's (cp_x, cp_y) coordinate. (The current cp_x and cp_y
- values can be found in the Rastport structure. see chapter 12
- LOWLEVELGRAPHICS for more information about Rastports).
-
- To change the printing position use the function Move()
- with a pointer to the Rastport that should be affected and
- the new coordinate as parameters.
-
- Synopsis: Move( rast_port, x, y );
-
- rast_port: (struct RastPort *) Pointer to the Rastport that
- should be affected.
-
- x: (long) The new X position.
-
- y: (long) The new Y position.
-
-
- When a character is printed the base line will be placed at the
- current cp_x, cp_y coordinate. The point below which is marked
- with a star (*) is the coordinate for the first character.
-
- 00000000000000000000000
- 00000000010000000000000
- 00000000010000000000000
- 00111100010000000000000
- 00000010010000000000000
- 00000010010000000000000
- 00000010010000000000000
- 00111110011111000111110
- 01000010010000101000010
- 01000010010000101000010
- 01000010010000101000010
- 01000010010000101000010
- *0111111011111000111110 <= Base line
- 00000000000000000000010
- 00000000000000000000010
- 00000000000000001000010
- 00000000000000000111100
- 00000000000000000000000
-
- If the base line is 13 lines below the top of the character, you
- must set the Y coordinate to 13 or higher, or the top part of
- the characters will not fit.
-
-
-
- 2.2.2 PRINT TEXT
-
- To print text on the Amiga you can use the low level Text()
- function which supports fonts of all sizes and all styles
- (more about this later).
-
- To print text you need a pointer to the Rastport which should
- be affected, a pointer to a text string and finally a value
- that tells Text() how many characters of the string should be
- printed. Only one line each call may be printed, and no
- formatting, word-wrapping etc is done. The Rastports current
- font will be used.
-
- Synopsis: Text( rast_port, string, nr_of_chr );
-
- rast_port: (struct RastPort *) Pointer to the RastPort that
- should be affected.
-
- string: (char *) Pointer to a text string that will be
- printed.
-
- nr_of_chr: (long) The number of characters that should be
- printed.
-
-
- Here is an example that prints "Hello" on the display:
- Text( &my_rast_port, "HELLO", 5 );
-
-
- The high level IntuiText structure also supports different
- types of fonts. See chapter 3 Graphics for more information
- about this structure and how to use it.
-
-
-
-
-
-
- 2.6 STYLES
-
- When you set your requirements in the TextAttr structure you
- can among many things specify what style (bold, underlined,
- italic, extended or a combination) you want the font to be in.
- If you are luck the font with your specified style exist. If
- not you can let the Amiga change the font into desired style
- by calling the SetSoftStyle() function.
-
- Before you use the SetSoftStyle() function you should call the
- AskSoftStyle() function to check if you are allowed to change
- the font as desired. The routines for changing the font style
- may not work very good with some fonts, and you are therefore
- sometimes advised not to change the style.
-
- For the moment there exist five different styles you may use.
- The header file "graphics/text.h" has defined them as:
- FS_NORMAL Normal style.
- FSF_EXTENDED Extra wide characters.
- FSF_ITALIC Italic (characters leaning to the right).
- FSF_BOLD Extra thick characters.
- FSF_UNDERLINED Underlined characters.
-
- To produce a combination of the styles you simply put the
- binary operator OR (|) between the flags.
-
-
- Note that you should always first try to load the font with the
- desired style. It is only when the desired style does not exist
- you should try to modify it with the SetSoftStyle() function.
-
- Synopsis: a_style = AskSoftStyle( rast_port )
-
- a_style: (UWORD) The function returns a bit field where the
- allowed style bits for the checked font are set. This
- value should be used as a parameter when you call
- the SetSoftStyle() function.
-
- rast_port: (struct RastPort *) Pointer to the rastport to which
- the font you want to check is connected.
-
-
- Once you know which styles you may use you can change the font
- by calling the SetSoftStyle() function.
-
- Synopsis: new_style = SetSoftStyle( rast_port, style, a_style );
-
- new_style: (UWORD) The function will only create the styles it
- is allowed to do (see a_styles), and it may therefore
- happen that the function will not generate all of the
- styles you wanted. This returned value tells us which
- style bits it used.
-
- rast_port: (struct RastPort *) Pointer to the rastport to which
- the font you want to change is connected.
-
- style: (UWORD) The desired style.
-
- a_style: (UWORD) The styles you may use. This value was
- returned by AskSoftStyle(). If you want to be able
- to use all styles and do not care if some styles
- would look strange set this field to 0xFFFF (all
- styles allowed). This can result in some very ugly
- styles, and is therefore not recommended.
-
-
- Here is an example:
-
- UWORD style; /* Desired style. */
- UWORD a_style; /* Styles allowed. */
- UWORD new_style; /* Style we got. */
-
-
- /* Set the desired style: (A combination of underlined, */
- /* bold and italic.) */
- style = FSF_UNDERLINED | FSF_BOLD | FSF_ITALIC;
-
- /* Check which styles we may use: */
- a_style = AskSoftStyle( my_window->RPort );
-
- /* Change the window's font style: */
- new_style = SetSoftStyle( my_window->RPort, style, a_style );
-
- /* Tell the user what style we will use: */
- printf( "Style:" );
- if( new_style )
- printf( "%s%s%s!\n",
- new_style & FSF_UNDERLINED ? " Underlined" : "",
- new_style & FSF_BOLD ? " Bold" : "",
- new_style & FSF_ITALIC ? " Italic" : "" );
- else
- printf( " normal!" );
- printf( "!\n" );
-
-
-
- 2.7 CREATING YOUR OWN FONTS
-
- If you want to create a new font yourself you should use the
- font editor program ("fed") which is included on the "Extras"
- disk you received when you bought your Amiga. To create your
- own fonts without this types of utility is very complicated.
- However, if you want to create a very small font set with a
- very limited number of characters it is possible to do it. I
- will here explain how to do this since it is rather interesting
- and good to know how a font set is actually constructed.
-
- If you want to include a font set together with your program
- code you do actually not need to do very much. I have written
- a small utility called PrintFont (in drawer "Include Font")
- which will load a specified font and print all information
- about it in C code. This code can then simply be included in
- your own program code.
-
- A font consists of:
-
- 1. A TextFont structure to which all other information of
- the font is connected to.
-
- 2. A memory area where the graphics of the font's characters
- are declared. (Character data)
-
- 3. A list of data which tells us where each character's
- fontdata begins and how wide each character is.
-
- 4. If it is a proportional font (each character has it's own
- width, for example an "i" is not as wide as a "W") we
- need information about how much space is needed between
- each character when printed. (Character Space). All
- proportional fonts does not need this array. If it does
- not exist the nominal width (tf_XSpace) will be used.
-
- 5. Finally, if the font is proportional we also need
- information about how many pixels to the right each
- character should be placed inside the the "character
- space". All proportional fonts does not need this array.
- If it does not exist the kerning (x offset) will be 0.
-
-
-
- 2.7.1 TEXTFONT STRUCTURE
-
- The TextFont structure which is declared in header file
- "graphics/text.h" is the foundation of all fonts. It consists
- of all information which is needed for the system to be able
- to print the characters. The structure looks like this:
-
- struct TextFont
- {
- struct Message tf_Message;
- UWORD tf_YSize;
- UBYTE tf_Style;
- UBYTE tf_Flags;
- UWORD tf_XSize;
- UWORD tf_Baseline;
- UWORD tf_BoldSmear;
- UWORD tf_Accessors;
- UBYTE tf_LoChar;
- UBYTE tf_HiChar;
- APTR tf_CharData;
- UWORD tf_Modulo;
- APTR tf_CharLoc;
- APTR tf_CharSpace;
- APTR tf_CharKern;
- };
-
- tf_Message: The top part of the text font structure consists
- of a message are. It is used by the system to
- communicate with other parts of the system. If
- the font is removed for example, a message is
- sent to all involved parts of the system.
-
- The Message structure is defined in header file
- "exec/ports.h" as:
-
- struct Message
- {
- struct Node mn_Node;
- struct MsgPort *mn_ReplyPort;
- UWORD mn_Length;
- };
-
- The Node structure is defined in header file
- "exec/nodes.h" as:
-
- struct Node
- {
- struct Node *ln_Succ;
- struct Node *ln_Pred;
- UBYTE ln_Type;
- BYTE ln_Pri;
- char *ln_Name;
- };
-
- See chapter 16 "Messages" for more information
- about these structures.
-
- If you want to initialize your own TextFont
- structure you should set the ln_Succ and ln_Pred
- field of the Node structure to NULL. The ln_Type
- to "NT_FONT" (font node), the ln_Pri to 0 (normal
- priority), and finally the ln_Name to a string
- which contains the name of the font.
-
- The mn_ReplyPort pointer of the Message structure
- should be set to NULL (Exec will take care of this
- later), and the length to the number of bytes is
- needed to store the whole font (including this
- structure, the name, and the arrays described
- below).
-
- tf_YSize: The height of the font (number of pixels/lines).
-
- tf_Style: The style bits as described above:
- FS_NORMAL Normal style.
- FSF_EXTENDED Extra wide characters.
- FSF_ITALIC Italic.
- FSF_BOLD Extra thick characters.
- FSF_UNDERLINED Underlined characters.
-
- tf_Flags: The font's special flags:
-
- FPF_ROMFONT The font is located in the ROM.
-
- FPF_DISKFONT The font is loaded from a disk.
- All fonts you design yourself
- must have this flag set unless
- you intend to burn your own
- memory chips.
-
- FPF_REVPATH The font should be printed in
- the opposite direction (right
- to left).
-
- FPF_TALLDOT The font is specially designed
- for high resolution screens
- with no interlace. (Each pixel
- is only half as wide as it is
- tall.)
-
- FPF_WIDEDOT The font is specially designed
- for low resolution screens
- which are interlaced. (Each
- pixel is only half as tall as
- it is wide.)
-
- FPF_PROPORTIONAL The font is proportional. The
- width of each character will
- vary depending on how wide the
- character is itself. The box
- containing an "i" will (usually)
- not be as wide as a "w" for
- example.
-
- FPF_DESIGNED If you have designed the font
- for the size specified in
- the "tf_ YSize" field this
- flag should be set. If a
- program has constructed this
- size of the font the flag
- should not be set. (The
- graphical quality of a
- Constructed font is usually not
- as good as a font which has
- been designed for this size.)
-
- FPF_REMOVED This flag is set by the system
- when it has been removed.
-
- tf_XSize: The nominal width of each character. If the font
- is normal (non proportional) this is the width
- between the first pixels of two characters. If a
- proportional font is used a special array of
- different width for each character may be used.
-
- tf_Baseline: The number of pixels down the baseline is from the
- top of the characters. You may not use a base line
- which is greater than the nominal height - 1
- (tf_YSize-1), or the system may crash!
-
- tf_BoldSmear: When you change the style to bold by calling the
- SetSoftStyle() function a copy of the font is
- placed on top of itself and a bit to the right.
- The further to the right, the bolder characters.
- This value represents the number of pixels to the
- right the characters should be moved. This value
- is usually set to 1, but large fonts usually need
- larger values.
-
- tf_Accessors: Several programs may use the same font
- simultaneously, and this value represents the
- current number of users. Each time the font
- is opened by a program this value is increased,
- and each time some one closes the font this value
- is decreased.
-
- tf_LoChar: A font can consist of up to 256 characters, but
- usually the font is much smaller. You can for
- example have a font which only consists of
- capital letters (A, B, C, .. Y, Z). This field
- tells us and the system which is the first
- character. In our example the value would be set
- to 65 (ASCII 65 = 'A').
-
- tf_HiChar: The last character in this font. In our example
- above this value would be set to 90 (ASCII 90 =
- 'Z').
-
- tf_CharData: Pointer to the character data (the graphics). See
- below for more information.
-
- tf_Modulo: The graphics (character data) for the characters
- are organized into lines. First comes the top line
- of all characters, then the second line and so
- on... This value represents the number of bytes
- needed for each line.
-
- tf_CharLoc: Pointer to a list of data which tells us where
- each character's data begins and how wide each
- character is.
-
- tf_CharSpace: Pointer to an array of space information - how
- much space is needed between each character when
- printed. If this pointer is NULL the nominal
- width (tf_XSpace) will be used for all
- characters.
-
- tf_CharKern: Pointer to an array of kerning data - how many
- pixels to the right the character should be moved
- inside its box (character space) when printed. If
- the pointer is NULL the kerning (x offset) will
- be 0.
-
-
-
- 2.7.2 FONT (CHARACTER) DATA
-
- The graphics for the characters are organized into an array
- of bit packed character data organized into words. Let's say
- we want to create our own font of five characters - A, B, C,
- D, and E. They should look like this:
-
- **** ***** **** **** ******
- ** * ** * ** * ** * **
- ** * ** * ** ** * **
- ****** ***** ** ** * *****
- ** * ** * ** ** * **
- ** * ** * ** * ** * **
- ** * ***** **** **** ******
-
-
- Although our font consist of five characters, we must also
- define an extra one which will be used when an non existing
- character is printed. If we try to print the character G
- which does not exist, this special character will be printed.
- This character is usually referred as the "not in this font
- character". In our example we will use a black box which
- looks like this:
-
- ********
- ********
- ********
- ********
- ********
- ********
- ********
- ********
-
-
- The characters should now be translated into C code. This
- is easiest done if you write the characters on a grid paper
- and organizes them into groups of four squares. Each group
- (binary values) can then easily be translated into hexadecimal
- as the following table shows: (Each marked square on your paper
- represents the digit '1' and each empty square represents the
- digit `0')
-
- Bin Hex
- ---------
- 0000 0
- 0001 1
- 0010 2
- 0011 3
-
- 0100 4
- 0101 5
- 0110 6
- 0111 7
-
- 1000 8
- 1001 9
- 1010 A
- 1011 B
-
- 1100 C
- 1101 D
- 1110 E
- 1111 F
-
-
- In our example our characters would be translated like this:
-
- -------------------------------------------------------------------------
- A B C D E * A B C D E *
- -------------------------------------------------------------------------
- 00111100 01111100 00111100 01111000 01111110 11111111 3C 7C 3C 78 7E FF
- 01100010 01100010 01100010 01100100 01100000 11111111 62 62 62 64 60 FF
- 01100010 01100010 01100000 01100010 01100000 11111111 62 62 60 62 60 FF
- 01111110 01111100 01100000 01100010 01111100 11111111 7E 7C 60 62 7C FF
- 01100010 01100010 01100000 01100010 01100000 11111111 62 62 60 62 60 FF
- 01100010 01100010 01100010 01100100 01100000 11111111 62 62 62 64 60 FF
- 01100010 01111100 00111100 01111000 01111110 11111111 62 7C 3C 78 7E FF
- 00000000 00000000 00000000 00000000 00000000 11111111 00 00 00 00 00 FF
- -------------------------------------------------------------------------
-
-
- Finally we put the hexadecimal values into an array of words:
-
- /* The font data: */
- UWORD MyOwnFontData[24]=
- {
- 0x3C7C,0x3C78,0x7EFF, /* Row 0 */
- 0x6262,0x6264,0x60FF, /* " 1 */
- 0x6262,0x6062,0x60FF, /* " 2 */
- 0x7E7C,0x6062,0x7CFF, /* " 3 */
- 0x6262,0x6062,0x60FF, /* " 4 */
- 0x6262,0x6264,0x60FF, /* " 5 */
- 0x627C,0x3C78,0x7EFF, /* " 6 */
- 0x0000,0x0000,0x00FF /* " 7 */
- };
-
-
-
- 2.7.3 CHARACTER LOCATION
-
- Secondly we need to tell the computer where each character exist
- in the character data, and how wide the character is. In our
- example all characters had the same width (8 pixels), but if we
- use a proportional font each character may have its own width.
-
- For every character two words are needed. The first word
- represents the offset position (the location of the character
- in the character data). The second word represents the width
- (in bits) of the character.
-
- In our example the character A has the offset value 0 since
- it is the first character. The second character (B) has the
- offset value 8 since the A was 8 bits wide. The third character
- has the offset value 16 (in hexadecimal it is 10) since both A
- and B was each 8 bits wide, and so on... All this information
- is stored in an array of "longs" (two words).
-
- /* The location and width of each character: */
- ULONG MyOwnFontLoc[5]=
- {
- 0x00000008, /* A: Offset 0[hex], Width 8 bits */
- 0x00080008, /* B: Offset 8[hex], Width 8 bits */
- 0x00100008, /* C: Offset 10[hex], Width 8 bits */
- 0x00180008, /* D: Offset 18[hex], Width 8 bits */
- 0x00200008 /* E: Offset 20[hex], Width 8 bits */
- };
-
-
-
- 2.7.4 CHARACTER SPACE
-
- Normally the default width (tf_XSize) is used as the space
- between the first pixel of two character. If the tf_Size is
- 12, the second character will be printed 12 pixels to the
- right and so on... However, if you are using a proportional
- font, each character may have its own space. The tf_CharSpace
- field should in this case point to an array of words where
- each word represents the space of one character. If the
- tf_CharSpace field is NULL the nominal width will be used.
- (See illustration "Proportional Fonts".)
-
- In our example we used a normal (non proportional) font, and
- hence we do not need any array of space information.
-
-
-
- 2.7.5 CHARACTER KERNING
-
- Some proportional fonts are using "kerning", which is a list
- of offset values. These offset values represent the number of
- pixels each character will be moved to the right inside its own
- character space. The tf_CharKern field must contain the address
- of this kerning list of words, or the kerning value 0 will be
- used. (See illustration "Proportional Fonts".)
-
- In our example we used a normal (non proportional) font, and
- hence we do not need any array of kerning data.
-
-
-
- 2.7.6 OUR OWN FONT EXAMPLE
-
- In our example the complete C code should look like this:
-
-
- #include <exec/types.h>
- #include <graphics/text.h>
-
- /* The font data: */
- UWORD MyOwnFontData[24]=
- {
- 0x3C7C,0x3C78,0x7EFF, /* Row 0 */
- 0x6262,0x6264,0x60FF, /* " 1 */
- 0x6262,0x6062,0x60FF, /* " 2 */
- 0x7E7C,0x6062,0x7CFF, /* " 3 */
- 0x6262,0x6062,0x60FF, /* " 4 */
- 0x6262,0x6264,0x60FF, /* " 5 */
- 0x627C,0x3C78,0x7EFF, /* " 6 */
- 0x0000,0x0000,0x00FF /* " 7 */
- };
-
- /* The location and width of each character: */
- ULONG MyOwnFontLoc[5]=
- {
- 0x00000008, /* A: Offset 0[hex], Width 8 bits */
- 0x00080008, /* B: Offset 8[hex], Width 8 bits */
- 0x00100008, /* C: Offset 10[hex], Width 8 bits */
- 0x00180008, /* D: Offset 18[hex], Width 8 bits */
- 0x00200008 /* E: Offset 20[hex], Width 8 bits */
- };
-
- /* The text font structure: */
- struct TextFont MyOwnFontFont=
- {
- {
- /* Message */
- {
- /* Node */
- NULL, /* ln_Succ */
- NULL, /* ln_Pred */
- NT_FONT, /* ln_Type */
- 0, /* ln_Pri */
- "OurFont.font" /* ln_Name */
- },
- NULL, /* mn_ReplyPort */
- 72 /* mn_Length */
- },
- 8, /* tf_YSize */
- 0, /* tf_Style */
- 66, /* tf_Flags */
- 8, /* tf_XSize */
- 6, /* tf_Baseline */
- 1, /* tf_BoldSmear */
- 0, /* tf_Accessors */
- 65, /* tf_LoChar */
- 69, /* tf_HiChar */
- (APTR) &MyOwnFontData, /* tf_CharData */
- 6, /* tf_Modulo */
- (APTR) &MyOwnFontLoc, /* tf_CharLoc */
- NULL, /* tf_CharSpace */
- NULL, /* tf_CharKern */
- };
-
-
-
- 2.8 FUNCTIONS
-
- OpenFont()
-
- This function is used to get access to a ROM font. You
- initialize a TextAttr structure with your requirements,
- and send a pointer to it as the only parameter. If
- OpenFont() finds the font it returns a pointer to a
- TextFont structure and tells the system that you are using
- the font. Remember to close all fonts you have opened with
- the CloseFont() function.
-
- Synopsis: font = OpenFont( attr );
-
- font: (struct TextFont *) Pointer to a TextFont structure
- or NULL if OpenFont() could not find the font.
-
- attr: (struct TextAttr *) Pointer to an initialized
- TextAttr structure. OpenFont() will try to open the
- font which closes matches your requirements.
-
-
- CloseFont()
-
- All fonts you have opened with the OpenFont() function must
- be "closed" before your program terminates! You close ROM
- fonts by calling the CloseFont() function.
-
- Synopsis: CloseFont( font );
-
- font: (struct TextFont *) Pointer to a previously opened
- TextFont structure. Note that you should NOT try to
- close a font which you have not opened!
-
-
- AvailFonts()
-
- This function will scan through the font directory of the
- system disk, and return a complete list of available fonts.
- Note that you must have opened the DiskFont Library before
- you may call this function.
-
- Synopsis: missing = AvailFonts( buffer, size, type );
-
- missing: (long) If the buffer was not big enough to store
- the complete list of fonts in the extra number of
- bytes needed is returned. If 0 is returned the
- buffer was big enough for a complete list of fonts.
-
- buffer: (char *) Pointer to some memory were the list of
- fonts can be stored.
-
- size: (long) The size of the buffer (in bytes).
-
- type: (long) If you want to look for available fonts
- which are already in the memory set the flag
- "AFF_MEMORY". If you want to search the disk for
- available fonts, set the flag "AFF_DISK". To
- search both the memory and the disk set both flags
- with the binary OR operator between:
- "AFF_DISK | AFF_MEMORY".
-
-
- OpenDiskFont()
-
- To load fonts from the disk and open them use the
- OpenDiskFont() function. Note that you must have opened the
- DiskFont Library before you may call this function. Remember
- to close all fonts you have opened!
-
- Synopsis: font = OpenDiskFont( attr );
-
- font: (struct TextFont *) Pointer to a TextFont structure
- or NULL if OpenFont() could not find the font.
-
- attr: (struct TextAttr *) Pointer to an initialized
- TextAttr structure. OpenDiskFont() will try to open
- the font which closes matches your requirements.
-
-
- SetFont()
-
- This function will change a RastPort's font. The font must
- of course have been successfully opened before you may start
- to use it.
-
- Synopsis: error = SetFont( rp, font );
-
- error: (long) If OK 0 is returned, else an error number is
- returned which means something went wrong.
-
- rp: (struct RastPort *) Pointer to the RastPort that
- should be affected.
-
- font: (struct TextFont *) Pointer to a TextFont structure
- which has previously been "opened".
-
-
- AskSoftStyle()
-
- This function tells us how a specified font may be changed,
- and which styles may be automatically created. Use the
- function SetSoftStyle() to later change style. The reason why
- you have to check if you are allowed to alter the style is
- that some fonts may look very bad when altered.
-
- Note that you should always first try to load the font with
- the desired style. It is only when the desired style does not
- exist you should try to modify it with the SetSoftStyle()
- function.
-
- Synopsis: a_style = AskSoftStyle( rast_port )
-
- a_style: (UWORD) The function returns a bit field where the
- allowed style bits for the checked font are set. This
- value should be used as a parameter when you later
- call the SetSoftStyle() function.
-
- rast_port: (struct RastPort *) Pointer to the rastport to
- which the font you want to check is connected.
-
-
- SetSoftStyle()
-
- This function will alter the style of a specified font. You
- should first find out which styles you may alter by calling
- the AskSoftStyle() function before you call this function.
-
- Synopsis: new_style = SetSoftStyle( rp, style, a_style );
-
- new_style: (UWORD) The function will only create the styles
- it is allowed to do (see a_styles), and it may
- therefore happen that the function will not
- generate all of the styles you wanted. This
- returned value tells us which style bits it used.
-
- rp: (struct RastPort *) Pointer to the rastport to
- which the font you want to change is connected.
-
- style: (UWORD) The desired style.
-
- a_style: (UWORD) The styles you may use. This value was
- returned by AskSoftStyle(). If you want to be able
- to use all styles and do not care if some styles
- would look strange set this field to 0xFFFF (all
- styles allowed). This can result in some very ugly
- styles, and is therefore not recommended.
-
-
- ClearEOL()
-
- This function will clear the area to the right of the current
- position. The height of the area which is cleared is set to
- fit the current font height.
-
- Synopsis: ClewarEOL( rp );
-
- rp: (struct RastPort *) Pointer to a rastport. The area
- from the current position to the right edge of the
- rastport is cleared. The height of the area
- depends on the current font size. Normally is the
- cleared area set to colour 0, but if you are using
- draw mode "JAM2" will the area be filled with the
- BgPen colour.
-
-
- ClearScreen()
-
- This function will clear the area to the right of the current
- position and the area below.
-
- Synopsis: ClewarScreen( rp );
-
- rp: (struct RastPort *) Pointer to a rastport. The area
- from the current position to the right edge of the
- rastport is cleared. The area below is also cleared.
- Normally is the cleared area set to colour 0, but
- if you are using draw mode "JAM2" will the area be
- filled with the BgPen colour.
-
-
- TextLength()
-
- This function will return the number of pixels wide the text
- string would be if printed with the rastport's current font.
-
- Synopsis: width = TextLength( rp, string, nr_chars );
-
- width: (long) Number of pixels wide the text string would
- be if printed with the rastport's current font.
-
- rp: (struct RastPort *) Pointer to the rastport.
-
- string: (char *) Pointer to the string containing the text
- you want to measure.
-
- nr_chars: (long) Number of characters in the string that
- should be counted.
-
-
-
- 2.9 EXAMPLES
-
- Example 1
- This example shows how to open the ROM font "Topaz". (Topaz
- is the standard system font, and is placed in ROM on all
- Amigas. If you have told preferences to use a 60-character
- display the 9 pixel size will be used, else (80-character
- display) the 8 pixel size will be used. This example prints
- some text in both sizes.
-
- Example 2
- This example demonstrates how to change the style of a font.
- We will open the ROM font "Topaz" and change the style to
- underlined, bold and italic. Well, we try to use all
- mentioned styles, but it may happen that we are not allowed
- to use some styles.
-
- Example 3
- This example demonstrates how to open a disk font (Opal, 12)
- and prints some characters with the new font in a window.
- Note! The font "Opal" must exist in the systems FONT:
- directory or you will receive an error message!
-
- Example 4
- This example opens disk fonts and prints some interesting
- information about them. (Height, width, flags, style, etc...)
- Syntax: Example4 [font1] [font2] [font3] ...
- (The largest size of each font will be used.)
-
- Example 5
- This example demonstrates how to use the AvailFonts()
- function. All available fonts (both on the disk as well as in
- the memory) will be listed together with some useful
- information about them.
-
- Example 6
- This example demonstrates how you can use a font loaded from
- a disk in your own Intuition programs.
-